package top.huxy.boot.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.huxy.boot.BlogApiApplication;
import top.huxy.boot.exception.RequestParamIllegalException;
import top.huxy.boot.mapper.ScheduleMapper;
import top.huxy.boot.model.dto.DTOSchedule;
import top.huxy.boot.model.entity.Admin;
import top.huxy.boot.model.entity.ScheduleJob;
import top.huxy.boot.service.ScheduleService;
import top.huxy.boot.util.StringUtils;
import top.huxy.boot.util.schedule.ScheduleUtils;

import java.util.List;

@Service
@Slf4j
public class ScheduleServiceImpl implements ScheduleService {

    @Autowired
    ScheduleUtils scheduleUtils;

    @Autowired
    ScheduleMapper scheduleMapper;

    @Override
    @Transactional
    public void addSchedule(DTOSchedule schedule, Admin admin) {
        //判断是否有该bean和指定方法
        if (!hasTargetMethod(schedule.getBeanName(), schedule.getMethodName(), schedule.getParam())) {
            throw new RequestParamIllegalException("没有找到指定目标");
        }

        ScheduleJob scheduleJob = new ScheduleJob(schedule, admin.getId());

        //插入数据库
        scheduleMapper.saveScheduleJob(scheduleJob);

        //获取刚刚插入的数据
        ScheduleJob job = scheduleMapper.selectByMaxID();

        //是否立即执行
        if (schedule.getEnable()) {
            scheduleUtils.addSchedule(job);
        }
    }

    @Override
    public List<ScheduleJob> getAllEnableScheduleJob() {
        return scheduleMapper.getAllEnableScheduleJobs();
    }

    private boolean hasTargetMethod(String beanName, String methodName, String arg) {
        try{
            Object bean = BlogApiApplication.app.getBean(beanName);
            if(StringUtils.isEmpty(arg)){
                bean.getClass().getMethod(methodName);
            }else{
                bean.getClass().getMethod(methodName, String.class);
            }
        }catch (Throwable e){
            return false;
        }

        return true;
    }

    @Override
    @Transactional
    public void stopSchedule(Integer scheduleId, Admin admin) {
        //从数据库修改数据
        scheduleMapper.setFalse(scheduleId);

        //从任务池中删除该任务
        scheduleUtils.stopSchedule(scheduleId);
    }

    @Override
    @Transactional
    public void enableSchedule(Integer scheduleId, Admin admin) {
        //从数据库修改数据
        scheduleMapper.setTrue(scheduleId);

        ScheduleJob scheduleJob=scheduleMapper.selectById(scheduleId);

        //添加任务
        scheduleUtils.addSchedule(scheduleJob);
    }

    @Override
    public List<ScheduleJob> getScheduleList() {
        return scheduleMapper.getScheduleList();
    }

    @Override
    public int getScheduleLogCount() {
        return scheduleMapper.getScheduleLogCount();
    }

    @Override
    public void runOnce(Integer scheduleId) {
        ScheduleJob schedule = scheduleMapper.getScheduleById(scheduleId);
        scheduleUtils.runOnce(schedule);
    }
}
